/*
 * Teknei 2014 - All rights reserved
 */
package com.teknei.acabus.core.controller;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

import org.apache.commons.collections.CollectionUtils;
import org.primefaces.model.DualListModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.teknei.acabus.FacadeException;
import com.teknei.acabus.core.common.MessageConstants;
import com.teknei.acabus.core.common.NavigationConstants;
import com.teknei.acabus.core.entities.NavigationChild;
import com.teknei.acabus.core.entities.NavigationChildRole;
import com.teknei.acabus.core.entities.Role;
import com.teknei.acabus.core.facade.NavigationFacade;

/**
 * Controller for updating the NavigationChild and Role elements
 * @author Jorge Amaro
 * @version 1.0
 * @since 1.0
 *
 */
@ViewScoped
@ManagedBean(name="ncr_edit_controller")
public class NavigationChildRoleControllerEdit extends GenericController implements Serializable{

	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	@EJB
	private NavigationFacade facadeNavigation;
	private List<Role> listRolesAssigned;
	private List<Role> listRolesUnassigned;
	private List<Role> listRoles;
	private DualListModel<Role> dualListModel;
	private NavigationChild currentItem;
	
	private static final Logger LOG = LoggerFactory.getLogger(NavigationChildRoleControllerEdit.class);

	/**
	 * PostConstruct method. Initialize items
	 */
	@PostConstruct
	private void postConstruct() {
		initItemList();
	}
	
	/**
	 * Pre-loads items and validates
	 */
	private void preInitItemList(){
		if(CollectionUtils.isEmpty(listRoles) || dualListModel == null){
			initItemList();
		}
	}
	
	/**
	 * Initialize items and lists
	 */
	private void initItemList(){
		try {
			currentItem = (NavigationChild) super.getFacesContext().getExternalContext().getSessionMap().get(NavigationConstants.EDIT_NAVIGATION_CHILD_RULE);
			listRoles = facadeNavigation.findRoles();
			listRolesAssigned = facadeNavigation.findRolesAllowed(currentItem);
			listRolesUnassigned = new ArrayList<Role>();
			Set<Role> setRoles = new HashSet<Role>(listRolesAssigned);
			for(Role role : listRoles){
				if(setRoles.add(role)){
					listRolesUnassigned.add(role);
				}
			}
			dualListModel = new DualListModel<Role>(listRolesUnassigned, listRolesAssigned);
		} catch (FacadeException e) {
			super.addErrorMessage(MessageConstants.ACTION_ERROR_INIT_LIST);
		}
	}
	
	/**
	 * Save the instance
	 * @return the action
	 */
	public String onSave(){
		for(Role role : dualListModel.getTarget()){
			LOG.debug("Role assigned: {}", role.getRoleName());
		}
		for(Role role : dualListModel.getSource()){
			LOG.debug("Role unassigned: {}", role.getRoleName());
		}
		List<NavigationChildRole> listParentRoles = new LinkedList<NavigationChildRole>();
		for(Role role : dualListModel.getTarget()){
			NavigationChildRole npr = new NavigationChildRole();
			npr.setChild(currentItem);
			npr.setRole(role);
			listParentRoles.add(npr);
		}
		currentItem.setNavigationChildRoles(listParentRoles);
		try {
			facadeNavigation.updateNavigationChildWithRoles(currentItem);
			super.addInfoMessage(MessageConstants.ACTION_UPDATE_SUCCESSFUL);
			return NavigationConstants.NAVIGATION_CHILD_ROLE_CATALOGUE;
		} catch (FacadeException e) {
			super.addErrorMessage(MessageConstants.ACTION_UPDATE_FAILURE);
			return NavigationConstants.NAVIGATION_SAME_PAGE;
		}
	}
	
	/**
	 * Cancels the action
	 * @return the action
	 */
	public String onSaveCancel(){
		super.addInfoMessage(MessageConstants.ACTION_CANCELLED);
		return NavigationConstants.NAVIGATION_SAME_PAGE;
	}
	
	/**
	 * Cancels the action and return to the catalothe page
	 * @return the action
	 */
	public String onCancel(){
		super.addInfoMessage(MessageConstants.ACTION_CANCELLED);
		return NavigationConstants.NAVIGATION_CHILD_ROLE_CATALOGUE;
	}

	
	
	/**
	 * @return the facadeNavigation
	 */
	public NavigationFacade getFacadeNavigation() {
		return facadeNavigation;
	}

	/**
	 * @param facadeNavigation the facadeNavigation to set
	 */
	public void setFacadeNavigation(NavigationFacade facadeNavigation) {
		this.facadeNavigation = facadeNavigation;
	}

	/**
	 * @return the listRolesAssigned
	 */
	public List<Role> getListRolesAssigned() {
		return listRolesAssigned;
	}

	/**
	 * @param listRolesAssigned the listRolesAssigned to set
	 */
	public void setListRolesAssigned(List<Role> listRolesAssigned) {
		this.listRolesAssigned = listRolesAssigned;
	}

	/**
	 * @return the listRolesUnassigned
	 */
	public List<Role> getListRolesUnassigned() {
		return listRolesUnassigned;
	}

	/**
	 * @param listRolesUnassigned the listRolesUnassigned to set
	 */
	public void setListRolesUnassigned(List<Role> listRolesUnassigned) {
		this.listRolesUnassigned = listRolesUnassigned;
	}

	/**
	 * @return the listRoles
	 */
	public List<Role> getListRoles() {
		return listRoles;
	}

	/**
	 * @param listRoles the listRoles to set
	 */
	public void setListRoles(List<Role> listRoles) {
		this.listRoles = listRoles;
	}

	/**
	 * @return the dualListModel
	 */
	public DualListModel<Role> getDualListModel() {
		preInitItemList();
		return dualListModel;
	}

	/**
	 * @param dualListModel the dualListModel to set
	 */
	public void setDualListModel(DualListModel<Role> dualListModel) {
		this.dualListModel = dualListModel;
	}

	/**
	 * @return the currentItem
	 */
	public NavigationChild getCurrentItem() {
		return currentItem;
	}

	/**
	 * @param currentItem the currentItem to set
	 */
	public void setCurrentItem(NavigationChild currentItem) {
		this.currentItem = currentItem;
	}
	
}
